home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / LINUX / MATH_EMU.ZIP / MATH_EMU / FPU_INT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1979-12-31  |  3.3 KB  |  123 lines

  1. /*        $NetBSD$  */
  2.  
  3. /*
  4.  * Copyright (c) 1995 Ken Nakata
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  *
  16.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26.  * SUCH DAMAGE.
  27.  *
  28.  *        @(#)fpu_int.c
  29.  */
  30.  
  31. #include "types.h"
  32.  
  33. #include "reg.h"
  34.  
  35. #include "fpu_arit.h"
  36. #include "fpu_emul.h"
  37.  
  38. /* FINTRZ - always round to zero */
  39. struct fpn *
  40. fpu_intrz(fe)
  41.      struct fpemu *fe;
  42. {
  43.   register struct fpn *x = &fe->fe_f2;
  44.   register int sh, clr, mask, i;
  45.  
  46.   /* special cases first */
  47.   if (x->fp_class != FPC_NUM) {
  48.     return x;
  49.   }
  50.   /* when |x| < 1.0 */
  51.   if (x->fp_exp < 0) {
  52.     x->fp_class = FPC_ZERO;
  53.     x->fp_mant[0] = x->fp_mant[1] = x->fp_mant[2] = x->fp_mant[3] = 0;
  54.     return x;
  55.   }
  56.  
  57.   /* real work */
  58.   sh = FP_NMANT - 1 - x->fp_exp;
  59.   if (sh <= 0) {
  60.     return x;
  61.   }
  62.  
  63.   clr = 3 - sh / 32;
  64.   mask = (0xffffffff << (sh % 32));
  65.  
  66.   for (i = 3; i > clr; i--) {
  67.     x->fp_mant[i] = 0;
  68.   }
  69.   x->fp_mant[i] &= mask;
  70.  
  71.   return x;
  72. }
  73.  
  74. /* FINT */
  75. struct fpn *
  76. fpu_int(fe)
  77.      struct fpemu *fe;
  78. {
  79.   register struct fpn *x = &fe->fe_f2;
  80.   register int rsh, lsh, wsh, i;
  81.  
  82.   /* special cases first */
  83.   if (x->fp_class != FPC_NUM) {
  84.     return x;
  85.   }
  86.   /* even if we have exponent == -1, we still have possiblity
  87.      that the result >= 1.0 when mantissa ~= 1.0 and rounded up */
  88.   if (x->fp_exp < -1) {
  89.     x->fp_class = FPC_ZERO;
  90.     x->fp_mant[0] = x->fp_mant[1] = x->fp_mant[2] = x->fp_mant[3] = 0;
  91.     return x;
  92.   }
  93.  
  94.   /* real work */
  95.   rsh = FP_NMANT - 1 - x->fp_exp;
  96.   if (rsh - FP_NG <= 0) {
  97.     return x;
  98.   }
  99.  
  100.   fpu_shr(x, rsh - FP_NG);    /* shift to the right */
  101.  
  102.   if (round(fe, x) == 1 /* rounded up */ &&
  103.       x->fp_mant[3 - (FP_NMANT-rsh)/32] & (1 << ((FP_NMANT-rsh)%32))
  104.       /* x >= 2.0 */) {
  105.     rsh--;                              /* reduce shift count by 1 */
  106.     x->fp_exp++;              /* adjust exponent */
  107.   }
  108.  
  109.   /* shift it back to the left */
  110.   wsh = rsh / 32;
  111.   lsh = rsh % 32;
  112.   rsh = 32 - lsh;
  113.   for (i = 0; i + wsh < 3; i++) {
  114.     x->fp_mant[i] = (x->fp_mant[i+wsh] << lsh) | (x->fp_mant[i+wsh+1] >> rsh);
  115.   }
  116.   x->fp_mant[i++] = (x->fp_mant[i+wsh] << lsh);
  117.   for (; i < 4; i++) {
  118.     x->fp_mant[i] = 0;
  119.   }
  120.  
  121.   return x;
  122. }
  123.